package com.ronghui.cash.controller;


import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.ronghui.cash.dto.ReturnFenqiBillBean;
import com.ronghui.cash.entity.*;
import com.ronghui.cash.parambean.*;
import com.ronghui.cash.service.*;
import com.ronghui.cash.util.*;
import com.ronghui.cash.vo.Response;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.text.ParseException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 用户表 前端控制器
 * </p>
 *
 * @author wiki
 * @since 2017-12-02
 */
@RestController
public class UserController extends BaseController {

    @Autowired
    UserService userService;

    @Autowired
    BCryptPasswordEncoder bCryptPasswordEncoder;

    @Autowired
    AuthBankService authBankService;

    @Autowired
    AuthProjectService authProjectService;

    @Autowired
    UserMsgService userMsgService;

    @Autowired
    OrdersService ordersService;

    @Autowired
    AuthIdentityService authIdentityService;

    @Value("${headImgUrl}")
    private String headImgUrl;

    @Value("${identityImgUrl}")
    private String identityImgUrl;

    @Value("${identityImgTempUrl}")
    private String identityImgTempUrl;

    /**
     * 注册
     *
     * @param userRegisterBean
     * @return
     */
    @RequestMapping("register")
    public Response register(@Validated UserRegisterBean userRegisterBean) {
        // 获取表单数据
        String mobile = userRegisterBean.getMobile();
        String password = userRegisterBean.getPassword();
        String vcode = userRegisterBean.getVcode();
        String invitationCode = userRegisterBean.getInvitationCode();

        String redisVcode = (String) redisTemplate.opsForValue().get("user:register:vcode:" + mobile);

        if (redisVcode == null) {
            return failure("验证码已失效");
        }

        if (!redisVcode.equals(vcode)) {
            return failure("验证码错误");
        }

        if (userService.checkUserExist(mobile).equals("exist")) {
            return failure("此用户已存在");
        }

        Long userId = super.getNextId();
        String dateTime = DateUtil.getCurrentDateTime();

        // 获取邀请人id
        Long invitationUserId = null;
        //TODO 查询邀请码对应的id,invitationUserId不等于null时，如果没有这个邀请码，要返回前端

        // 邀请码信息
        Invite invite = null;
        if (invitationUserId != null) {
            invite = new Invite();
            invite.setId(super.getNextId());
            invite.setInviteStart(invitationUserId);
            invite.setInviteEnd(userId);
            invite.setCreateTime(dateTime);
            invite.setStatus(1);
        }

        // 用户信息
        User user = new User();
        user.setId(userId);
        user.setCreateTime(dateTime);
        user.setUsername(mobile);
        user.setStatus(1);
        //密码加密
        password = bCryptPasswordEncoder.encode(password);
        user.setPassword(password);
        userService.register(user, invite);

        String token = super.setTokenOnRedis(userId);
        return success(token);
    }


    /**
     * 登录
     *
     * @param MobileAndPassword
     * @return
     */
    @RequestMapping("login")
    public Response login(@Validated MobileAndPassword MobileAndPassword) {
        String mobile = MobileAndPassword.getMobile();
        String password = MobileAndPassword.getPassword();

        User user = userService.selectOne(new EntityWrapper<User>().eq("username", mobile));
        if (user == null) {
            return failure("此用户不存在");
        }
        if (user.getStatus() == 2) {
            return failure("此帐号封停中");
        }

        Long userId = user.getId();

        // TODO 登录失败5次后要做冻结24小时的功能
        if (!bCryptPasswordEncoder.matches(password, user.getPassword())) {
            return failure("帐号或密码错误");
        }

        String token = super.setTokenOnRedis(userId);

        return success(token);
    }

    @RequestMapping("checkUserExist")
    public Response checkUserExist(@Validated MobileBean mobileBean) {
        return success(userService.checkUserExist(mobileBean.getMobile()));
    }

    /**
     * 修改昵称
     *
     * @param nicknameBean
     * @return
     */
    @RequestMapping(method = RequestMethod.POST, value = "user/modifyNickname")
    public Response postModifyNickname(@Validated NicknameBean nicknameBean) {
        String nickname = nicknameBean.getNickname();
        if (userService.checkNickname(nickname).equals("exist")) {
            return failure("昵称已存在");
        }
        Long userId = super.getUserId();
        User user = userService.selectById(userId);
        user.setNickname(nickname);
        userService.updateById(user);
        return success();
    }

    /**
     * 检查昵称是否重复
     *
     * @param nicknameBean
     * @param request
     * @return
     */
    @RequestMapping(method = RequestMethod.POST, value = "checkNickname")
    public Response getCheckNickname(@Validated NicknameBean nicknameBean, HttpServletRequest request) {
        return success(userService.checkNickname(nicknameBean.getNickname()));
    }

    /**
     * 修改密码
     *
     * @param mpb
     * @return
     */
    @RequestMapping("user/modifyPassword")
    public Response get_modifyPassword(@Validated ModifyPasswordBean mpb) {
        Long userId = super.getUserId();
        String oldPassword = mpb.getOldPassword();
        String newPassword = mpb.getNewPassword();
        User user = userService.selectById(userId);
        if (user == null) {
            return failure("此用户不存在");
        }
        if (!bCryptPasswordEncoder.matches(oldPassword, user.getPassword())) {
            return failure("旧密码错误");
        }
        // 密码加密
        newPassword = bCryptPasswordEncoder.encode(newPassword);

        user.setPassword(newPassword);
        userService.updateById(user);
        return success();
    }

    /**
     * 修改头像
     *
     * @param file
     * @return
     * @throws IllegalStateException
     * @throws IOException
     */
    @RequestMapping(method = RequestMethod.POST, value = "user/modifyHeadIcon")
    public Response post_modifyHeadIcon(MultipartFile file) throws IllegalStateException, IOException {

        if (file.isEmpty()) {
            return failure("文件为空");
        }
        Long userId = getUserId();

        User user = userService.selectById(userId);

        String fileName = FileUtil.saveFile(file, headImgUrl, headImgUrl + user.getHeadIcon());
        user.setHeadIcon(fileName);
        userService.updateById(user);

        return success(fileName);
    }

    /**
     * 获取银行卡信息
     *
     * @return
     */
    @RequestMapping("user/getUserBankInfo")
    public Response getUserBankInfo() {
        Long userId = getUserId();
        AuthBank ab = authBankService.selectOne(new EntityWrapper<AuthBank>().eq("user_id", userId));
        return success(ab);
    }

    /**
     * 忘记密码，重新设置
     *
     * @param fpb
     * @return
     */
    @RequestMapping("findPassword")
    public Response findPassword(@Validated FindPasswordBean fpb) {
        String mobile = fpb.getMobile();
        String newPassword = fpb.getNewPassword();
        String vcode = fpb.getVcode();
        String key = "user:findPassword:vcode:" + mobile;
        String redisVcode = (String) redisTemplate.opsForValue().get(key);

        if (redisVcode == null) {
            return failure("验证码已失效");
        }
        if (!redisVcode.equals(vcode)) {
            return failure("验证码错误");
        }
        User user = userService.selectOne(new EntityWrapper<User>().eq("username", mobile));

        if (user == null) {
            return failure("此用户不存在");
        }

        // 做密码加密加盐，userId也是盐的一部分
        newPassword = bCryptPasswordEncoder.encode(newPassword);

        user.setPassword(newPassword);
        userService.updateById(user);

        // 删除用过的验证码
        redisTemplate.delete(key);
        return success();
    }

    //验证码登录
    @RequestMapping("loginByVcode")
    public Response loginByVcode(@Validated MobileAndVcode mav) {
        String mobile = mav.getMobile();
        String redisVcode = (String) redisTemplate.opsForValue().get("user:login:vcode:" + mobile);
        if (redisVcode == null) {
            return failure("验证码已失效");
        }
        if (!redisVcode.equals(mav.getVcode())) {
            return failure("验证码错误");
        }
        User user = userService.selectOne(new EntityWrapper<User>().eq("username", mobile));
        if (user == null) {
            return failure("此用户不存在");
        }

        String token = super.setTokenOnRedis(user.getId());
        return success(token);
    }

    //用户基本信息
    @RequestMapping("user/getUserInfo")
    public Response getUserInfo() {
        Long userId = getUserId();
        User user = userService.selectById(userId);
        if(user == null){
            return failure("用户不存在");
        }

        String nickname = user.getNickname();
        if (nickname == null) {
            nickname = Util.mobileFormat(user.getUsername());
        }

        String headIcon = user.getHeadIcon();
        if (headIcon == null){
            headIcon = "default.jpg";
        }

        AuthIdentity ai = authIdentityService.selectOne(new EntityWrapper<AuthIdentity>().eq("user_id",userId));

        List<ReturnFenqiBillBean> fenqiBills = ordersService.getCurrentFenqiBill(userId);

        Double returnMoney = 0d;
        for (int i = 0; fenqiBills != null && i < fenqiBills.size(); i++) {
            returnMoney = Util.add(returnMoney, fenqiBills.get(i).getMoney());
        }

        List<FenqiBill> allFenqiBills = ordersService.getMyAllFenqiBill(userId);

        String returnMoneyDateTag = "最近还款日";
        String returnMoneyDate = "— —";
        if (allFenqiBills != null && allFenqiBills.size() > 0) {
            FenqiBill fenqiBill = allFenqiBills.get(0);
            try {
                if (DateUtil.compareDate(fenqiBill.getDate())) {
                    returnMoneyDateTag = "逾期";
                }
                returnMoneyDate = DateUtil.convertFormat(fenqiBill.getDate());
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }

        Integer userMsgCount = userMsgService.selectCount(new EntityWrapper<UserMsg>()
                .eq("user_id", userId)
                .eq("status",1)
        );
        Integer ordersCount = ordersService.selectCount(new EntityWrapper<Orders>()
                        .eq("user_id",userId)
                //.notIn("status",-2)
        );

        List<AuthBank> authBanks = authBankService.selectList(new EntityWrapper<AuthBank>()
                .eq("user_id", super.getUserId())
        );

        Map<String, Object> result = new HashMap<String, Object>();
        result.put("headIcon", headIcon);
        result.put("nickname", nickname);
        result.put("currentMonthMoney", Util.double2String(returnMoney));
        result.put("returnMoneyDate", returnMoneyDate);
        result.put("returnMoneyDateTag", returnMoneyDateTag);
        result.put("userMsgCount", userMsgCount);
        result.put("ordersCount", ordersCount);
        result.put("adentityAuditStatus", (ai == null? null : ai.getAuditStatus()));

        return success(result);
    }

    /**
     * 用户认证情况
     * @return
     */
    @RequestMapping("user/getUserAuthInfo")
    public Response getUserAuthInfo() {
        Long userId = getUserId();
        User user = userService.selectById(userId);

        if (user == null) {
            return failure("用户不存在");
        }

        int baiqishi = 0;
        int basicinfo = 0;
        int contact = 0;
        int bank = 0;
        int phone = 0;
        int taobao = 0;
        List<AuthProject> apList = authProjectService.selectList(new EntityWrapper<AuthProject>().eq("user_id", userId));
        for (AuthProject ap : apList) {
            switch (ap.getType()) {
                case ConstUtil.BAIQISHI:
                    baiqishi = 1;
                    break;
                case ConstUtil.BASICINFO:
                    basicinfo = 1;
                    break;
                case ConstUtil.CONTACT:
                    contact = 1;
                    break;
                case ConstUtil.BANK:
                    bank = 1;
                    break;
                case ConstUtil.MOBILE:
                    phone = 1;
                    break;
                case ConstUtil.TAOBAO:
                    taobao = 1;
                    break;
                default:
                    break;
            }
        }

        Map<String, Object> result = new HashMap<String, Object>();
        result.put("baiqishi", baiqishi);
        result.put("basicinfo", basicinfo);
        result.put("contact", contact);
        result.put("bank", bank);
        result.put("phone", phone);
        result.put("taobao", taobao);
        return success(result);
    }
}
